package com.wang.wangrpc.server;

import com.wang.wangrpc.RpcApplication;
import com.wang.wangrpc.model.RpcRequest;
import com.wang.wangrpc.model.RpcResponse;
import com.wang.wangrpc.registry.LocalRegistry;
import com.wang.wangrpc.serializer.JdkSerializer;
import com.wang.wangrpc.serializer.Serializer;
import com.wang.wangrpc.serializer.SerializerFactory;
import com.wang.wangrpc.serializer.SerializerKeys;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @Author 王子旭
 * @Date 2025/04/02 23:02
 * @Version 1.0
 */
@Slf4j
public class HttpServerHandler implements Handler<HttpServerRequest> {

    @Override
    public void handle(HttpServerRequest request) {
        // 指定序列化器
        final Serializer serializer = SerializerFactory.getInstance(RpcApplication.getRpcConfig().getSerializer());
        log.info("Received request:{} {}",request.method(),request.absoluteURI());
        request.bodyHandler(body->{
            byte[] bytes = body.getBytes();
            RpcRequest rpcRequest = null;
            try {
                rpcRequest = serializer.deserialize(bytes, RpcRequest.class);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            RpcResponse rpcResponse = new RpcResponse();
            if (rpcRequest == null) {
                rpcResponse.setMessage("rpcRequest is null");
                doResponse(request,rpcResponse,serializer);
                return;
            }
            try {
                Class<?> implClass = LocalRegistry.get(rpcRequest.getServiceName());
                log.info("{},{}",rpcRequest.getMethodName(),rpcRequest.getParameterTypes());
                Method method = implClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
                Object object = method.invoke(implClass.newInstance(), rpcRequest.getArgs());
                rpcResponse.setData(object);
                rpcResponse.setDataType(method.getReturnType());
                rpcResponse.setMessage("ok");
            } catch (Exception e) {
                e.printStackTrace();
                rpcResponse.setException(e);
            }
            doResponse(request,rpcResponse,serializer);
        });
    }

    /**
     * 响应
     * @param request 当前处理的网络请求
     * @param rpcResponse 当前的响应封装到RpcResponse中
     * @param serializer 指定序列化器
     */
    private void doResponse(HttpServerRequest request, RpcResponse rpcResponse, Serializer serializer) {
        HttpServerResponse httpServerResponse = request.response()
                .putHeader("content-type","application/json");
        try {
            byte[] serialized = serializer.serialize(rpcResponse);
            httpServerResponse.end(Buffer.buffer(serialized));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
